package com.yb.livewykt.vm

import android.app.Application
import android.util.Log
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.google.gson.JsonObject
import com.netease.nimlib.sdk.NIMClient
import com.netease.nimlib.sdk.RequestCallback
import com.netease.nimlib.sdk.chatroom.ChatRoomMessageBuilder
import com.netease.nimlib.sdk.chatroom.ChatRoomService
import com.netease.nimlib.sdk.chatroom.ChatRoomServiceObserver
import com.netease.nimlib.sdk.chatroom.constant.MemberQueryType
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMember
import com.netease.nimlib.sdk.chatroom.model.ChatRoomMessage
import com.netease.nimlib.sdk.msg.model.QueryDirectionEnum
import com.yb.livewykt.bean.*
import com.yb.livewykt.net.LiveUrl
import com.yb.livewykt.util.*
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File

class LiveStreamingViewModel(application: Application) : BaseViewModel(application) {

    val historyData = MutableLiveData<LiveRTMP>()
    val startLiveRTMP = MutableLiveData<LiveRTMP>()
    val isLiving = MutableLiveData<Boolean>()
    val chatRoomMessagesLiveData = MutableLiveData<ChatRoomTextMsg>()
    val liveExitRoomLiveData = MutableLiveData<Boolean>()
    val roomPersonLiveData = MutableLiveData<List<ChatRoomPerson>>()
    val receiveGiftLiveData = MutableLiveData<ChatRoomGiftMsg>()

    val canEditTitle = MutableLiveData<Boolean>()

    init {
        isLiving.value = false
        liveExitRoomLiveData.value = false
        canEditTitle.value = true
    }

    fun getLastTimeData(){
        launch({userApi.getHistoryLiveData()},historyData)
    }

    fun startLive(isUploadCover:Boolean,filePath:String,title:String){
        val file = File(filePath)
        if (isUploadCover){
            if (!file.exists()){
                return
            }else if (file.isDirectory){
                return
            }
        }
        val builder = MultipartBody.Builder().setType(MultipartBody.FORM)
        val body = RequestBody.create(MediaType.parse("multipart/form-data"),file)
        if (isUploadCover) builder.addFormDataPart("file",file.name,body)
        builder.addFormDataPart("channel_id","1")
        builder.addFormDataPart("name",title)
        launch ({userApi.startLive(builder.build().parts())},startLiveRTMP)
    }

    //发送文本信息
    fun sendTextMessage(connect: String){
        if (connect.isEmpty()){
            NOT_INPUT_SOMETHING.showToast()
        }
        val textMsg = TextMessage(
            connect,
            SaveUserData.get().username,
            SaveUserData.get().id.toString(),
            SaveUserData.get().accId,
            SaveUserData.get().role,
            SaveUserData.get().role
        )
        val chatRoomCustomMsg = ChatRoomTextMsg(
            responseSuccessCode,
            reponseDefaultMsg,
            System.currentTimeMillis(),
            textMsg
        )
        val chatRoomMsg = ChatRoomMessageBuilder.createChatRoomTextMessage(
            startLiveRTMP.value?.room_id.toString(), Gson().toJson(
                chatRoomCustomMsg
            )
        )
        NIMClient.getService(ChatRoomService::class.java).sendMessage(chatRoomMsg, false).setCallback(
            object : RequestCallback<Void> {
                override fun onSuccess(param: Void?) {
                    chatRoomMessagesLiveData.value = chatRoomCustomMsg
                }

                override fun onFailed(code: Int) {
                    Log.d(TAG, "onFailed: $code")
                }

                override fun onException(exception: Throwable?) {
                    exception?.printStackTrace()
                }
            })
    }



//    fun joinChatRoom(){
//        val enterChatRoom = EnterChatRoomData(startLiveRTMP.value?.room_id.toString())
//        NIMClient.getService(ChatRoomService::class.java).enterChatRoomEx(enterChatRoom, 3).setCallback(
//            object : RequestCallback<EnterChatRoomResultData> {
//                override fun onSuccess(param: EnterChatRoomResultData?) {
//                    isObserverMessage(true)
//                    getChatRoomHistoryMessage()
//                }
//
//                override fun onFailed(code: Int) {
//                    Log.d(TAG, "onFailed: $code")
//                }
//
//                override fun onException(exception: Throwable?) {
//                    Log.d(TAG, "onException: ${exception?.message}")
//                }
//
//            })
//    }

    private fun sendExitLive(){
        val textMsg = TextMessage("",SaveUserData.get().username,SaveUserData.get().id.toString(),SaveUserData.get().accId,1,SaveUserData.get().role)
        val exitMsg = ChatRoomTextMsg(EXIT_LIVE, responseTokenFailedMsg,System.currentTimeMillis(),textMsg)
        val exitMessage = ChatRoomMessageBuilder.createChatRoomTextMessage(startLiveRTMP.value?.room_id.toString(),Gson().toJson(exitMsg))
        NIMClient.getService(ChatRoomService::class.java).sendMessage(exitMessage,true)
    }

    //是否开始监听消息
    fun isObserverMessage(isStart: Boolean){
        NIMClient.getService(ChatRoomServiceObserver::class.java)
            .observeReceiveMessage({
                if (it.isNotEmpty()) {
                    it.forEach { chatMsg ->
                        val msg = JsonObject().getAsJsonObject(chatMsg.content)
                        val code = msg.get("code").asInt
                        if (code == responseSuccessCode) {
                            //chatRoomMessageLiveData.value?.add(chatMessage)
                            chatRoomMessagesLiveData.value = Gson().fromJson(chatMsg.content,ChatRoomTextMsg::class.java)
                        } else if (code == RECEIVE_GIFT) {
                            receiveGiftLiveData.value = Gson().fromJson(chatMsg.content,ChatRoomGiftMsg::class.java)
                        }
                    }
                }
            }, isStart)
    }

    fun getChatRoomHistoryMessage(){

        Log.d(TAG, "getChatRoomHistoryMessage: ${startLiveRTMP.value?.room_id}")

        NIMClient.getService(ChatRoomService::class.java)
            .pullMessageHistoryEx(startLiveRTMP.value?.room_id.toString(), System.currentTimeMillis(), 50, QueryDirectionEnum.QUERY_OLD).setCallback(
                object : RequestCallback<MutableList<ChatRoomMessage>> {
                    override fun onSuccess(param: MutableList<ChatRoomMessage>?) {
                        if (!param.isNullOrEmpty()) {
                            param.forEach {
                                if (!it.content.startsWith("{") && !it.content.endsWith("}")) {
                                    return@forEach
                                }
                                val message = Gson().fromJson<ChatRoomTextMsg>(
                                    it.content,
                                    ChatRoomTextMsg::class.java
                                )
                                if (message.code == responseSuccessCode) {
                                    message.time = it.time
                                    chatRoomMessagesLiveData.value = message
                                } else if (message.code == EXIT_LIVE) {
                                    liveExitRoomLiveData.value = true
                                }
                            }
                        }
                    }

                    override fun onFailed(code: Int) {
                        Log.d(TAG, "onFailed: $code")
                    }

                    override fun onException(exception: Throwable?) {
                        Log.d(TAG, "onException: ${exception?.message}")
                    }
                })
    }

    fun getChatRoomPerson(){
        NIMClient.getService(ChatRoomService::class.java).fetchRoomMembers(
            startLiveRTMP.value?.room_id.toString(),
            MemberQueryType.GUEST,
            0,
            20
        ).setCallback(
            object : RequestCallback<MutableList<ChatRoomMember>> {
                override fun onSuccess(param: MutableList<ChatRoomMember>?) {
                    val personList: MutableList<ChatRoomPerson> = ArrayList()
                    if (param?.isNotEmpty()!!) {
                        param.forEach {
                            personList.add(
                                ChatRoomPerson(
                                    it.account,
                                    it.nick,
                                    LiveUrl.headerBaseUrl + it.account
                                )
                            )
                        }
                        roomPersonLiveData.value = personList
                    }
                }

                override fun onFailed(code: Int) {
                    Log.d(TAG, "onFailed: $code")
                }

                override fun onException(exception: Throwable?) {
                    exception?.printStackTrace()
                }

            })
    }

    fun exitLive(){
        sendExitLive()
        launch { userApi.closeLive(startLiveRTMP.value?.room_id!!) }
    }


}